#include "render_control_software_win32.h"
#include "render_control_software.h"
#include "window_win32.h"
#include <iostream>
#include <windows.h>
#include "widget_helper_win32.h"

using namespace krryn::system_imp;
using namespace krryn::gui;
using namespace krryn::view;

#pragma comment(lib, "gdiplus.lib")

void render_control_software_impl_win32::make(const krryn::gui::render_control_software_initializer &a_Initializer){
	/// token is needed for gdiplusshutdown
	ULONG_PTR l_Token;
	Gdiplus::GdiplusStartupInput l_Input;
	Gdiplus::GdiplusStartup(&l_Token, &l_Input, NULL);

	widget_helper_win32::create_window(a_Initializer, m_hWnd, m_hDC);

	m_Graphics = new Gdiplus::Graphics(m_hDC);
	m_Graphics->Clear(Gdiplus::Color::Black);

	RECT l_WindowRect;
	GetClientRect(m_hWnd, &l_WindowRect);

	// passing graphics object doesn't work, probably because 
	// the native pixel format is different form this one.
	m_Bitmap = new Gdiplus::Bitmap(
		l_WindowRect.right - l_WindowRect.left,
		l_WindowRect.bottom - l_WindowRect.top, 
		PixelFormat32bppRGB
	);

	m_Canvas = new canvas();
	m_Canvas->clear(0);

	std::clog << "Created win32 software rendering context." << std::endl;
}

void render_control_software_impl_win32::destroy_window(const krryn::gui::render_control_software_initializer &a_Initializer){

}

void render_control_software_impl_win32::make_current(){
}

canvas *render_control_software_impl_win32::lock(){
	// lock the GDI+ canvas
	Gdiplus::Rect l_Rect(0, 0, m_Bitmap->GetWidth(), m_Bitmap->GetHeight());
	m_Bitmap->LockBits(&l_Rect, NULL, m_Bitmap->GetPixelFormat(), &m_Data);

	// prepare the canvas
	m_Canvas->set_buffer((pixel_t*)m_Data.Scan0);
	m_Canvas->set_height(m_Data.Height);
	m_Canvas->set_width(m_Data.Width);
	m_Canvas->set_pitch(m_Data.Stride / sizeof(pixel_t));

	m_Canvas->lock();
	
	return m_Canvas;
}

void render_control_software_impl_win32::unlock(){
	/// fix RGB <> BGR problem (GDI returns BGR, we use RGB)

	pixel_t *l_Current = m_Canvas->get_buffer();
	pixel_t *l_End = l_Current + m_Canvas->get_height() * m_Canvas->get_pitch();

	//while(l_Current < l_End){
	//	*l_Current++ = 
	//		  ((*l_Current & 0xFF0000) >> 16)
	//		+ ((*l_Current & 0x00FF00))
	//		+ ((*l_Current & 0x0000FF) << 16);
	//}

	m_Bitmap->UnlockBits(&m_Data);
	m_Canvas->unlock();
}

void render_control_software_impl_win32::swap_buffers(){
	m_Graphics->DrawImage(m_Bitmap, 0, 0, m_Bitmap->GetWidth(), m_Bitmap->GetHeight());
}